<?php
/**
 *------------------------------------------------
 * Author: YYT[QQ:375776626]
 *------------------------------------------------
 */

//根据配置来继承对应的数据库驱动
$driver = Web::config('db_memcache') ? 'Memcache' : Web::config('db_driver');
$eval = 'class ModelDbDriver extends Db'.$driver.'{}';
eval($eval);

abstract class Model extends ModelDbDriver
{
    public function __construct()
    {
        $table = strtolower(substr(get_class($this), 0, -5));
        $this->setTable($table);
    }

    public static function strlen($str)
    {
        preg_match_all('/./us', $str, $match);
        return count($match['0']);
    }

    /**
     * 验证数据(使用异常来捕获)
     * @param 数据
     * @param 验证方法名
     * @param 验证规则
     * @param 错误信息
     * @throw
     */
    public static function check($value, $checkName, $rules, $error)
    {
        switch ($checkName) {
            case 'len':
                $value = trim($value);
            case 'len-trim':
                if (!strstr($rules, '-')) {
                    if (self::strlen($value) != $rules) throw new Exception($error);
                } else {
                    list($min, $max) = explode('-', $rules);
                    if (!$max) {
                        if (self::strlen($value) < $rules) throw new Exception($error);
                    } else if (!(self::strlen($value) >= $min && self::strlen($value) <= $max)) {
                        throw new Exception($error);
                    }
                }
                break;
            case 'inc':
                if ($rules == '__html__') {
                    $rules = array('<', '>', '"', '&');
                    $value = html_entity_decode($value);
                }
                if (is_array($rules)) {
                    foreach ($rules as $rule) {
                        if (stristr($value, $rule)) throw new Exception($error);
                    }
                } else if (stristr($value, $rules)) {
                    throw new Exception($error);
                }
                break;
            case 'eq':
                $value = trim($value);
                if (is_array($rules)) {
                    foreach ($rules as $rule) {
                        if ($value == $rule) throw new Exception($error);
                    }
                } else if ($value == $rules) {
                    throw new Exception($error);
                }
                break;
            default:
                throw new Exception('不支持该验证方式: '.$checkName);
        }
    }

    public $validate = array();

    private function _validate($data)
    {
        if ($this->validate) {
            $data = $this->filterData($data);
            if ($data) { //字段存在才验证
                //$validate[0]字段名 $validate[1]验证方法 $validate[2]验证规则 $validate[3]返回信息
                foreach ($this->validate as $validate) {
                    if (isset($data[$validate[0]])) {
                        if ($validate[1] == 'unique') { //unique $validate[2]返回信息
                            if ($this->where(array($validate[0] => $data[$validate[0]]))->field($validate[0])->fetch()) {
                                throw new Exception($validate[2]);
                            }
                        } else {
                            self::check($data[$validate[0]], $validate[1], $validate[2], $validate[3]);
                        }
                    }
                }
            }
        }
    }

    public function insert($data)
    {
        $this->_validate($data);
        return parent::insert($data);
    }

    public function update($data)
    {
        $this->_validate($data);
        return parent::update($data);
    }
}